home *** CD-ROM | disk | FTP | other *** search
- /*
- * ACKNOWLEDGEMENTS
- *
- * ZMDM was derived from rz/sz for Unix posted by
- * Chuck Forsberg (...!tektronix!reed!omen!caf ). We
- * thank him for his excellent code, and for giving
- * us permission to use and distribute his code and
- * documentation.
- *
- * Atari St version by:
- * Jwahar Bammi
- * usenet: cwruecmp!bammi@decvax.UUCP
- * csnet: bammi@cwru.edu
- * arpa: bammi@cwru.edu
- * CompuServe: 71515,155
- */
-
- #define RVERSION "rz 1.14 01-15-87"
- #define RSTVERSION "rz 1.01 03-07-87"
- #define OS "Unix V7/BSD"
-
- /* #define RDEBUG */ /* a lot of debugging garb */
-
- /*
- * ATARI ST series implementation notes:
- *
- * - the following command line options were removed as they
- * were either not applicable to the ST environment or
- * were not deemed reasonable (by me - ofcourse).
- * 1 Not Applicable here as we have a seperate
- * serial port.
- * 7 In this day and age? Forget it, get another m/c.
- * a/b Ascii/Binary - the receive mode (if not
- * over-ridden by the sender) is automatically
- * selected depending on the extention given
- * in the incoming file name. This idea was
- * present in earlier rz/sz, i wonder why such
- * a convenient feature was dropped (Chuck ??).
- * This feature is relevant to ZMODEM only in rz,
- * as the sender determines the file mode in
- * XMODEM/YMODEM transfers.
- * B Note that `B' has a special meaning.
- * Specifying -B will force override to
- * binary mode for each incoming file. Useful
- * when doing St-to-St transfers.
- * D There is no /dev/null on the ST's
- * u not applicable to TOS. Upper and lower
- * case file names are the same. All the
- * applicable routines like uncap() and
- * IsAnyLower() were zapped.
- *
- * - The [-][v]rzCOMMAND style of invocation was dropped
- * as there is no good way to do pipes without the
- * microRtx kernal. All references to Pipe and popen()
- * were zapped.
- * - Verbose is always set to 2 by automatically, as we know that
- * stdout != stderr. This can be overridden
- * by specifying -q to ensure that Verbose = 0
- * - The idea of a PUBDIR and Restricted paths in the origonal
- * code was dropped totally as it is not applicable
- * to the single owner ST environment. 1 man 1 machine.
- * - CRCTABLE is default always, hey we have plenty of memory!.
- * - LOGFILE renamed to 'rzlog/szlog' as we don't always have
- * a meaningful environment to pick up TMPDIR from (like when
- * running from the desktop).
- * - When a subdirectory in an incoming path name is not
- * present it is created.
- * - The file mode transmitted is 0S00 where S is derived from
- * the Read/Write attribute of the file on the ST
- * - When a file mode is received, only the owner bits are
- * are checked. If it was read only (r--) on the Unix sytem
- * then it is given read only attribute on the ST, read-write
- * otherwise.
- * - Of course all the I/O was completely redone on the ST.
- * - You will find two versions of VARARGS routines like log,
- * one that takes int args, and the other that takes long
- * (address) args, since sizeof(int) != sizeof(long)
- * and sizeof(int) != sizeof(pointer) on the ST.
- *
- * ST v1.01
- * added support for 32 bit CRC's for Zmodem ++jrb
- *
- */
-
- /*% cc -DNFGVMIN -DCRCTABLE -K -O % -o rz; size rz
- *
- * rz.c By Chuck Forsberg
- *
- * cc -O rz.c -o rz USG (3.0) Unix
- * cc -O -DV7 rz.c -o rz Unix V7, BSD 2.8 - 4.3
- *
- * ln rz rb For either system
- *
- * ln rz /usr/bin/rzrmail For remote mail. Make this the
- * login shell. rzrmail then calls
- * rmail(1) to deliver mail.
- *
- * define CRCTABLE to use table driven CRC
- *
- * Unix is a trademark of Western Electric Company
- *
- * A program for Unix to receive files and commands from computers running
- * Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM.
- * rz uses Unix buffered input to reduce wasted CPU time.
- *
- * Iff the program is invoked by rzCOMMAND, output is piped to
- * "COMMAND filename"
- *
- * Some systems (Venix, Coherent, Regulus) may not support tty raw mode
- * read(2) the same way as Unix. ONEREAD must be defined to force one
- * character reads for these systems. Added 7-01-84 CAF
- *
- * Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF
- *
- * NFGVMIN Added 1-13-85 CAF for PC-AT Xenix systems where c_cc[VMIN]
- * doesn't seem to work (even though it compiles without error!).
- *
- * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin
- */
-
-
- #include "zmdm.h"
- #include "common.h"
- #include "zmodem.h"
-
- static unsigned long SaveIntr;
-
- #ifdef MWC
- extern FILE *fopen();
- #else
- extern FILE *fopen(), *fopenb();
- #endif
-
- /* called by simulated signal interrupt or terminate to clean things up */
- bibi(n)
- int n;
- {
-
- if (Zmodem)
- zmputs(Attn);
- canit(); mode(0);
- fprintf(stderr, "\r\nrz: caught signal %d; exiting", n);
- if (fout != -1)
- {
- if (stfclose(fout) != 0)
- {
- fprintf(stderr, "\r\nfile close ERROR\n");
- }
- fout = (-1);
-
- }
-
- #ifdef RDEBUG
- if (logf != (FILE *)NULL)
- fclose(logf);
- #endif
- aexit(128+n);
- }
-
- dorz(argc, argv)
- int argc;
- char **argv;
- {
- register char *cp;
- register int npats;
- char **patts;
- int exitcode;
-
- SendType = 0;
- Rxtimeout = 100;
- exitcode = 0;
-
- initz();
-
- chkinvok(argv[0]); /* if called as 'rb' set flag */
- npats = 0;
- SaveIntr = Setexc(0x0102, -1L);
- BusErr = Setexc(2, -1L);
- AddrErr = Setexc(3, -1L);
- vdebug = 0;
-
- while (--argc)
- {
- cp = *++argv;
- if (*cp == '-')
- {
- while( *++cp)
- {
- switch(*cp)
- {
- case '+':
- Lzmanag = ZMAPND; break;
- case 'B':
- ForceBinary=TRUE; break;
- case 'c':
- Crcflg=TRUE; break;
- case 'p':
- Lzmanag = ZMPROT; break;
- case 'q':
- Quiet=TRUE; Verbose=0; break;
- case 't':
- if (--argc < 1) {
- rusage();
- return(1);
- }
- Rxtimeout = atoi(*++argv);
- if (Rxtimeout<10 || Rxtimeout>1000)
- {
- rusage();
- return(1);
- }
- break;
- case 'v':
- ++Verbose; break;
- default:
- rusage();
- return(1);
- }
- }
- }
- else if ( !npats && argc>0)
- {
- if (argv[0][0])
- {
- npats=argc;
- patts=argv;
- }
- }
- }
-
- if (npats > 1)
- {
- rusage();
- return(1);
- }
-
- #ifdef RDEBUG
- if (Verbose > 2)
- {
- if ((logf = fopen(RLOGFILE, "a"))== (FILE *)NULL)
- {
- fprintf(stderr, "Can't open log file %s\n",RLOGFILE);
- return(0200);
- }
- fprintf(logf, "Progname=%s\n", Progname);
- vdebug = 1;
- }
- #endif
-
- if ( !Quiet)
- {
- if (Verbose == 0)
- Verbose = 2;
- }
-
- Setexc(0x0102, bibi);
-
- Setexc(2, buserr);
- Setexc(3, addrerr);
-
- if((exitcode = setjmp(abrtjmp)))
- {
- /* on Contrl-C */
- canit();
- Setexc(2, BusErr);
- Setexc(3, AddrErr);
- Setexc(0x0102, SaveIntr);
- return(exitcode);
- }
-
- if(setjmp(busjmp))
- {
- /* On a bus error - instead of 2 bombs */
- fprintf(stderr,"\r\nFATAL: Bus Error\n\n");
- #ifdef RDEBUG
- if(logf != (FILE *)NULL)
- fclose(logf);
- #endif
- if(fout != -1)
- {
- if (stfclose(fout) != 0)
- {
- fprintf(stderr, "\r\nfile close ERROR\n");
- }
- fout = (-1);
- }
- canit();
- Setexc(2, BusErr);
- Setexc(3, AddrErr);
- Setexc(0x0102, SaveIntr);
-
- return(2);
- }
-
- if(setjmp(addrjmp))
- {
- /* On address error - instead of 3 bombs */
- fprintf(stderr,"\r\nFATAL: Address Error\n\n");
- #ifdef RDEBUG
- if(logf != (FILE *)NULL)
- fclose(logf);
- #endif
- if(fout != -1)
- {
- if (stfclose(fout) != 0)
- {
- fprintf(stderr, "\r\nfile close ERROR\n");
- }
- fout = (-1);
- }
- canit();
- Setexc(2, BusErr);
- Setexc(3, AddrErr);
- Setexc(0x0102, SaveIntr);
-
- return(3);
- }
-
- mode(1);
-
- if (wcreceive(npats, patts)==ERROR)
- {
- exitcode=0200;
- canit();
- }
-
- mode(0);
- if (exitcode && !Zmodem) /* bellow again with all thy might. */
- canit();
-
- #ifdef RDEBUG
- if(logf != (FILE *)NULL)
- fclose(logf);
- #endif
-
- if(fout != -1)
- {
- if (stfclose(fout) != 0)
- {
- fprintf(stderr, "\r\nfile close ERROR\n");
- }
- fout = (-1);
- }
- Setexc(2, BusErr);
- Setexc(3, AddrErr);
- Setexc(0x0102, SaveIntr);
-
- return(exitcode);
- }
-
-
- rusage()
- {
- fprintf(stderr,
- "%s for %s by ST Enthusiasts at Case Western Reserve University\n",
- RSTVERSION, STOS);
- fprintf(stderr, "\tBased on %s for %s by Chuck Forsberg\n\n",
- RVERSION, OS);
-
- fprintf(stderr,"Usage: rz [-Bpqtv] (ZMODEM Batch)\n");
- fprintf(stderr,"or rb [-qtv] (YMODEM Batch)\n");
- fprintf(stderr,"or rz [-cqtv] file (XMODEM or XMODEM-1k)\n");
- fprintf(stderr," -v Verbose more v's give more info\n");
- fprintf(stderr," -q Quiet suppresses verbosity\n");
- fprintf(stderr," -t TIM Change timeout to TIM tenths of seconds\n");
- fprintf(stderr," -c Use 16 bit CRC (XMODEM)\n");
- fprintf(stderr," -p Protect existing dest. file by skipping\n");
- fprintf(stderr," transfer if the dest. file exists (ZMODEM ONLY)\n\n");
-
-
- if(fout != -1)
- {
- if (stfclose(fout) != 0)
- {
- fprintf(stderr, "\r\nfile close ERROR\n");
- }
- fout = (-1);
- }
-
- #ifdef RDEBUG
- if(logf != (FILE *)NULL)
- fclose(logf);
- #endif
-
- return(1);
- }
-
-
- /*
- * Let's receive something already.
- */
- wcreceive(argc, argp)
- int argc;
- char **argp;
- {
- register int c;
-
- if (Batch || argc==0)
- {
- Crcflg=(Wcsmask==0377);
- if ( !Quiet)
- fprintf(stderr, "\n%s: ready (CTRL-C to cancel)\n\n",
- Progname);
-
- if (c=tryz())
- {
- if (c == ZCOMPL)
- return OK;
- if (c == ERROR)
- goto fubar;
- c = rzfiles();
- if (c)
- goto fubar;
- }
- else
- {
- for (;;)
- {
- if (wcrxpn(secbuf)== ERROR)
- goto fubar;
- if (secbuf[0]==0)
- return OK;
- if (procheader(secbuf) == ERROR)
- goto fubar;
- if (wcrx()==ERROR)
- goto fubar;
- }
- }
- }
- else
- {
- Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
-
- strcpy(Pathname, *argp);
- fprintf(stderr, "\n%s: ready to receive %s (CTRL-C to Cancel)\n\n",
- Progname, Pathname);
- #ifdef RDEBUG
- if(logf != (FILE *)NULL)
- fprintf(logf, "\nrz: ready to receive %s ", Pathname);
- #endif
-
- if((fout = stfopen(Pathname,"w")) <= 0)
- return ERROR;
- if (wcrx()==ERROR)
- goto fubar;
- }
- return OK;
-
- fubar:
- canit();
-
- if (fout != -1)
- {
- if (stfclose(fout) != 0)
- {
- fprintf(stderr, "\r\nfile close ERROR\n");
- }
- fout = (-1);
- }
-
- return ERROR;
- }
-
-
- /*
- * Fetch a pathname from the other end as a C ctyle ASCIZ string.
- * Length is indeterminate as long as less than Blklen
- * A null string represents no more files (YMODEM)
- */
- wcrxpn(rpn)
- char *rpn; /* receive a pathname */
- {
- register int c;
-
- PURGELINE;
-
- et_tu:
- Firstsec=TRUE; Eofseen=FALSE;
- sendline(Crcflg?WANTCRC:NAK);
- Lleft=0; /* Do read next time ... */
- while ((c = wcgetsec(rpn, 100)) != 0)
- {
- llog( "Pathname fetch returned %d\n", c);
- if (c == WCEOT)
- {
- sendline(ACK);
- Lleft=0; /* Do read next time ... */
- readline(1);
- goto et_tu;
- }
- return ERROR;
- }
- sendline(ACK);
- return OK;
- }
-
- /*
- * Adapted from CMODEM13.C, written by
- * Jack M. Wierda and Roderick W. Hart
- */
-
- wcrx()
- {
- register int sectnum, sectcurr;
- register char sendchar;
- int cblklen; /* bytes to dump this block */
-
- Firstsec=TRUE;sectnum=0; Eofseen=FALSE;
- sendchar=Crcflg?WANTCRC:NAK;
-
- for (;;)
- {
- sendline(sendchar); /* send it now, we're ready! */
- Lleft=0; /* Do read next time ... */
- sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130);
- report(sectcurr);
- if (sectcurr==(sectnum+1 &Wcsmask))
- {
- sectnum++;
- cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
- if (putsec(secbuf, cblklen)==ERROR)
- return ERROR;
- if ((Bytesleft-=cblklen) < 0)
- Bytesleft = 0;
- sendchar=ACK;
- }
- else if (sectcurr==(sectnum&Wcsmask))
- {
- log2( "Received dup Sector\n");
- sendchar=ACK;
- }
- else if (sectcurr==WCEOT)
- {
- if (closeit())
- return ERROR;
- sendline(ACK);
- Lleft=0; /* Do read next time ... */
- return OK;
- }
- else if (sectcurr==ERROR)
- return ERROR;
- else
- {
- log2( "Sync Error\n");
- return ERROR;
- }
- }
- }
-
-
- /*
- * Wcgetsec fetches a Ward Christensen type sector.
- * Returns sector number encountered or ERROR if valid sector not received,
- * or CAN CAN received
- * or WCEOT if eot sector
- * time is timeout for first char, set to 4 seconds thereafter
- ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
- * (Caller must do that when he is good and ready to get next sector)
- */
- wcgetsec(rxbuf, maxtime)
- char *rxbuf;
- int maxtime;
- {
- register int checksum, wcj, firstch;
- register unsigned int oldcrc;
- register char *p;
- int sectcurr;
-
- for (Lastrx=errors=0; errors<RETRYMAX; errors++)
- {
-
- if ((firstch=readline(maxtime))==STX)
- {
- Blklen=KSIZE; goto get2;
- }
- if (firstch==SOH)
- {
- Blklen=SECSIZ;
- get2:
- sectcurr=readline(1);
- if ((sectcurr+(oldcrc=readline(1)))==Wcsmask)
- {
- oldcrc=checksum=0;
- for (p=rxbuf,wcj=Blklen; --wcj>=0; )
- {
- if ((firstch=readline(1)) < 0)
- goto bilge;
- oldcrc=updcrc(firstch, oldcrc);
- checksum += (*p++ = firstch);
- }
- if ((firstch=readline(1)) < 0)
- goto bilge;
- if (Crcflg)
- {
- oldcrc=updcrc(firstch, oldcrc);
- if ((firstch=readline(1)) < 0)
- goto bilge;
- oldcrc=updcrc(firstch, oldcrc);
- if (oldcrc & 0xFFFF)
- llog("CRC=0%o\n", oldcrc);
- else
- {
- Firstsec=FALSE;
- return sectcurr;
- }
- }
- else if (((checksum-firstch)&Wcsmask)==0)
- {
- Firstsec=FALSE;
- return sectcurr;
- }
- else
- log2( "Checksum Error\n");
- }
- else
- log2("Sector number garbled 0%o 0%o\n",
- sectcurr, oldcrc);
- }
- /* make sure eot really is eot and not just mixmash */
-
- else if (firstch==EOT && Lleft==0)
- return WCEOT;
-
- else if (firstch==CAN)
- {
- if (Lastrx==CAN)
- {
- log2( "Sender CANcelled\n");
- return ERROR;
- }
- else
- {
- Lastrx=CAN;
- continue;
- }
- }
- else if (firstch==TIMEOUT)
- {
- if (Firstsec)
- goto humbug;
- bilge:
- log2( "Timeout\n");
- }
- else
- llog( "Got 0%o sector header\n", firstch);
-
- humbug:
- Lastrx=0;
- while(readline(1)!=TIMEOUT)
- ;
- if (Firstsec)
- {
- sendline(Crcflg?WANTCRC:NAK);
- Lleft=0; /* Do read next time ... */
- }
- else
- {
- maxtime=40; sendline(NAK);
- Lleft=0; /* Do read next time ... */
- }
- }
- /* try to stop the bubble machine. */
- canit();
- return ERROR;
- }
-
- /*
- * This version of readline is reasonably well suited for
- * reading many characters.
- * timeout is in tenths of seconds
- */
- int readline(timeout)
- int timeout;
- {
- register int n;
- static char *cdq; /* pointer for removing chars from linbuf */
-
- if (--Lleft >= 0)
- {
- #ifdef RDEBUG
- if (Verbose > 8)
- {
- fprintf(logf, "%02x ", *cdq&0377);
- }
- #endif
-
- return (*cdq++ & Wcsmask);
- }
- /* n = timeout/10; */
- n = timeout >> 3; /* close enough for rock and roll - see alarm() */
- if (n < 2)
- n = 3;
- #ifdef RDEBUG
- if (Verbose > 3)
- fprintf(logf, "Calling read: n=%d ", n);
- #endif
-
- if (setjmp(tohere))
- {
- Lleft = 0;
- #ifdef RDEBUG
- if (Verbose>3)
- {
- fprintf(stderr, "Readline:TIMEOUT\n");
- fprintf(logf, "Readline:TIMEOUT\n");
-
- }
- #endif
- return TIMEOUT;
- }
- stalarm(n);
- Lleft=read_modem(cdq=linbuf, Readnum);
- stalarm(0);
-
- #ifdef RDEBUG
- if (Verbose > 3)
- {
- fprintf(logf, "Read returned %d bytes\n", Lleft);
- }
- #endif
-
- if (Lleft < 1)
- return TIMEOUT;
- --Lleft;
-
- #ifdef RDEBUG
- if (Verbose > 8)
- {
- fprintf(logf, "%02x ", *cdq&0377);
- }
- #endif
-
- return (*cdq++ & Wcsmask);
- }
-
-
-
-
- /*
- * Process incoming file information header
- */
- procheader(name)
- char *name;
- {
- register char *p;
- register int dot;
- char openmode[4];
- extern int strlen();
-
- /* convert to ST style path names */
- for( p = name; *p != '\0'; p++)
- {
- if(*p == '/')
- *p = '\\';
- }
-
- /* pick out the last extention in the filename in each part of path */
- while(p != name)
- {
- dot = 0; p-- ;
- while((p != name) && (*p != '\\'))
- {
- if(*p == '.')
- {
- if(dot == 0)
- {
- dot = 1;
- }
- else
- {
- /* replace all but the last dot with '_' */
- *p = '_';
- }
- }
- p--;
- }
- }
-
- /* set default parameters and overrides */
- strcpy(openmode,"w");
-
- Thisbinary = isbinary(name);
-
- if (Lzmanag)
- zmanag = Lzmanag;
-
- /*
- * Process ZMODEM remote file management requests
- */
- if ( zconv == ZCNL) /* Remote ASCII override */
- Thisbinary = 0;
- if (zconv == ZCBIN) /* Remote Binary override */
- ++Thisbinary;
- else if (zmanag == ZMAPND)
- strcpy(openmode, "a");
-
- if (ForceBinary == TRUE ) /* local binary force override */
- ++Thisbinary;
-
- /* ZMPROT check for existing file */
- if (zmanag == ZMPROT && existf(name, "r"))
- {
- return ERROR;
- }
-
- /* ATARI ST NOTE:
- * We will not accept rooted paths ie. paths that begin in '\' or '.\'
- * If the incoming filename is rooted, we skip the beginning
- * '\' '.\' or '..\'
- */
-
- if( (name[0] == '\\') || (name[0] == '.') )
- {
- /* skip over the leading stuff */
- if(name[0] == '\\')
- name = &name[1];
- else
- {
- if(name[1] == '.')
- name = &name[3]; /* Skip the "..\" */
- else
- name = &name[2]; /* Skip the ".\" */
- }
- }
-
- /* ST addition, create any dierctories in the path that don't exist */
- if( pathensure(name) == ERROR)
- return ERROR;
-
- Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
-
- p = name + 1 + strlen(name);
- if (*p)
- { /* file coming from Unix or DOS system */
- sscanf(p, "%ld%lo%o", &Bytesleft, &Modtime, &Filemode);
- /* NA to atari
- if (Filemode & UNIXFILE)
- ++Thisbinary;
- */
- if (Verbose)
- {
- fprintf(stderr,
- "\nIncoming:\n\tName:\t%s\n\tBytes:\t%ld\n\tModTime: %ld\n\tMode:\t%o\n\n",
- name, Bytesleft, Modtime, Filemode);
-
- #ifdef RDEBUG
- if(logf != (FILE *)NULL)
- fprintf(logf, "Incoming: %s %ld %lo %o\n",
- name, Bytesleft, Modtime, Filemode);
- #endif
-
- }
- }
- else
- { /* File coming from CP/M system */
- for (p=name; *p; ++p) /* change / to _ */
- if ( *p == '/')
- *p = '_';
-
- if ( *--p == '.') /* zap trailing period */
- *p = 0;
- }
-
- strcpy(Pathname, name);
- if (Verbose)
- {
- fprintf(stderr, "Receiving %s %s [mode %s]\n\n",
- name, Thisbinary?"BIN":"ASCII", openmode);
-
- #ifdef RDEBUG
- if(logf != (FILE *)NULL)
- fprintf(logf, "Receiving %s %s %s\n",
- name, Thisbinary?"BIN":"ASCII", openmode);
- #endif
-
- }
-
-
- if ((fout=stfopen(name, openmode)) <= 0)
- return ERROR;
-
- return OK;
- }
-
- /*
- * Putsec writes the n characters of buf to receive file fout.
- * If not in binary mode, all characters
- * starting with CPMEOF are discarded.
- */
- putsec(buf, n)
- unsigned char *buf;
- register int n;
- {
- register unsigned char *p;
-
- if (Thisbinary)
- {
- for (p=buf; --n>=0; p++ )
- {
- if(stputc( *p, fout) < 0)
- {
- fprintf("\r\nError while Writing file\n");
- return ERROR;
- }
- }
- }
- else
- {
- if (Eofseen)
- return OK;
-
- for (p=buf; --n>=0; p++ )
- {
- if (*p == CPMEOF)
- {
- Eofseen=TRUE;
- return OK;
- }
- if(*p == '\n')
- {
- if(stputc('\r' ,fout) < 0)
- {
- fprintf("\r\nError while Writing file\n");
- return ERROR;
- }
- }
- if(stputc(*p ,fout) < 0)
- {
- fprintf("\r\nError while Writing file\n");
- return ERROR;
- }
- }
- }
-
- return OK;
- }
-
- /*
- * Log an error only if high verbose
- */
- /*VARARGS1*/
- llog(s,p,u)
- char *s;
- int p, u;
- {
- if (Verbose < 3)
- return;
- #ifdef RDEBUG
- fprintf(logf, "error %d: ", errors);
- fprintf(logf, s, p, u);
- #endif
-
- fprintf(stderr, "\nerror %d: ", errors);
- fprintf(stderr, s, p, u);
- }
-
- /*
- * Log an error if verbose
- */
-
- /*VARARGS1*/
- log2(s,p,u)
- char *s;
- int p, u;
- {
- if (!Verbose)
- return;
- fprintf(stderr, "\nerror %d: ", errors);
- fprintf(stderr, s, p, u);
-
- #ifdef RDEBUG
- if(Verbose > 3)
- {
- fprintf(logf, "error %d: ", errors);
- fprintf(logf, s, p, u);
- }
- #endif
-
- }
-
- report(sct)
- int sct;
- {
- if (Verbose>1)
- fprintf(stderr,"%03d%c",sct,sct%10? ' ' : '\r');
- }
-
- lreport(sct)
- long sct;
- {
- if (Verbose>1)
- fprintf(stderr,"%06ld%c",sct,lsct%10? ' ' : '\r');
- lsct++;
- }
-
-
- /*
- * If called as rb use YMODEM protocol
- */
- chkinvok(s)
- char *s;
- {
- Progname = s;
- if (s[0]=='r' && s[1]=='b')
- Nozmodem = TRUE;
- }
-
-
- /*
- * Initialize for Zmodem receive attempt, try to activate Zmodem sender
- * Handles ZSINIT frame
- * Return ZFILE if Zmodem filename received, -1 on error,
- * ZCOMPL if transaction finished, else 0
- */
- tryz()
- {
- register int n;
- register int cmdzack1flg;
-
- if (Nozmodem) /* Check for "rb" program name */
- return 0;
-
-
- for (n=Zmodem?10:5; --n>=0; )
- {
- /* Set buffer length (0) and capability flags */
- stohdr(0L);
- Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK; /* of course we can break */
-
- zshhdr(tryzhdrtype, Txhdr);
- /* zshhdr(Badclose?ZFERR:ZRINIT, Txhdr); */
- again:
- switch (zgethdr(Rxhdr, 0))
- {
- case ZRQINIT:
- continue;
- case ZEOF:
- continue;
- case TIMEOUT:
- continue;
- case ZFILE:
- zconv = Rxhdr[ZF0];
- zmanag = Rxhdr[ZF1];
- ztrans = Rxhdr[ZF2];
- tryzhdrtype = ZRINIT;
- Badclose = FALSE;
- if (zrdata(secbuf, KSIZE) == GOTCRCW)
- return ZFILE;
- zshhdr(ZNAK, Txhdr);
- goto again;
- case ZSINIT:
- if (zrdata(Attn, ZATTNLEN) == GOTCRCW)
- {
- zshhdr(ZACK, Txhdr);
- goto again;
- }
- zshhdr(ZNAK, Txhdr);
- goto again;
- case ZFREECNT:
- stohdr(~0L);
- zshhdr(ZACK, Txhdr);
- goto again;
- case ZCOMMAND:
- cmdzack1flg = Rxhdr[ZF0];
- if (zrdata(secbuf, KSIZE) == GOTCRCW)
- {
- if (cmdzack1flg & ZCACK1)
- stohdr(0L);
- else
- stohdr((long)sys2(secbuf));
- PURGELINE; /* dump impatient questions */
- do {
- zshhdr(ZCOMPL, Txhdr);
- }
- while (++errors<10 && zgethdr(Rxhdr,1) != ZFIN);
- ackbibi();
- if (cmdzack1flg & ZCACK1)
- exec2(secbuf);
- return ZCOMPL;
- }
- zshhdr(ZNAK, Txhdr); goto again;
- case ZCOMPL:
- goto again;
- default:
- continue;
- case ZFIN:
- ackbibi(); return ZCOMPL;
- case ZCAN:
- return ERROR;
- }
- }
- return 0;
- }
-
- /*
- * Receive 1 or more files with ZMODEM protocol
- */
- rzfiles()
- {
- register int c;
-
- for (;;) {
- switch (c = rzfile()) {
- case ZEOF:
- case ZSKIP:
- switch (tryz()) {
- case ZCOMPL:
- return OK;
- default:
- return ERROR;
- case ZFILE:
- break;
- }
- continue;
- default:
- return c;
- case ERROR:
- return ERROR;
- }
- }
- }
-
- /*
- * Receive a file with ZMODEM protocol
- * Assumes file name frame is in secbuf
- */
- rzfile()
- {
- register int c, n;
- long rxbytes;
-
- Eofseen=FALSE;
- if (procheader(secbuf) == ERROR) {
- return (tryzhdrtype = ZSKIP);
- /* zshhdr(ZSKIP, Txhdr);
- return ZSKIP; */
- }
-
- n = 10; rxbytes = 0L;
-
- for (;;)
- {
- stohdr(rxbytes);
- zshhdr(ZRPOS, Txhdr);
- nxthdr:
- switch (c = zgethdr(Rxhdr, 0)) {
- default:
- vfile("rzfile: zgethdr returned %d", c);
- return ERROR;
- case ZNAK:
- case TIMEOUT:
- if ( --n < 0)
- {
- vfile("rzfile: zgethdr returned %d", c);
- return ERROR;
- }
- case ZFILE:
- zrdata(secbuf, KSIZE);
- continue;
- case ZEOF:
- /* ++jrb */
- if (rclhdr(Rxhdr) != rxbytes)
- {
- /*
- * Ignore eof if it's at wrong place - force
- * a timeout because the eof might have gone
- * out before we sent our zrpos.
- */
-
- errors = 0; goto nxthdr;
- }
- /* --jrb if (rclhdr(Rxhdr) != rxbytes)
- {
- continue;
- } */
- if (closeit())
- {
- tryzhdrtype = ZFERR;
- Badclose = TRUE;
- vfile("rzfile: closeit returned <> 0");
- return ERROR;
- }
- vfile("rzfile: normal EOF");
- return c;
- case ERROR: /* Too much garbage in header search error */
- if ( --n < 0)
- {
- vfile("rzfile: zgethdr returned %d", c);
- return ERROR;
- }
- zmputs(Attn);
- continue;
- case ZDATA:
- n = 10;
- if (rclhdr(Rxhdr) != rxbytes)
- {
- zmputs(Attn);
- continue;
- }
- moredata:
- switch (c = zrdata(secbuf, KSIZE))
- {
- case ZCAN:
- vfile("rzfile: zgethdr returned %d", c);
- return ERROR;
- case ERROR: /* CRC error */
- if ( --n < 0)
- {
- vfile("rzfile: zgethdr returned %d", c);
- return ERROR;
- }
- zmputs(Attn);
- continue;
- case TIMEOUT:
- if ( --n < 0)
- {
- vfile("rzfile: zgethdr returned %d", c);
- return ERROR;
- }
- continue;
- case GOTCRCW:
- if(putsec(secbuf, Rxcount) == ERROR)
- return ERROR;
- rxbytes += Rxcount;
- lreport(rxbytes);
- stohdr(rxbytes);
- zshhdr(ZACK, Txhdr);
- goto nxthdr;
- case GOTCRCQ:
- if(putsec(secbuf, Rxcount) == ERROR)
- return ERROR;
- rxbytes += Rxcount;
- lreport(rxbytes);
- stohdr(rxbytes);
- zshhdr(ZACK, Txhdr);
- goto moredata;
- case GOTCRCG:
- if(putsec(secbuf, Rxcount) == ERROR)
- return ERROR;
- rxbytes += Rxcount;
- lreport(rxbytes);
- goto moredata;
- case GOTCRCE:
- if(putsec(secbuf, Rxcount) == ERROR)
- return ERROR;
- rxbytes += Rxcount;
- lreport(rxbytes);
- goto nxthdr;
- }
- }
- }
- }
-
- /*
- * Send a string to the modem, processing for \336 (sleep 1 sec)
- * and \335 (break signal)
- */
- zmputs(s)
- char *s;
- {
- register int c;
-
- while (*s) {
- switch (c = *s++) {
- case '\336':
- stsleep(1); continue;
- case '\335':
- sendbrk(); continue;
- default:
- sendline(c);
- }
- }
- }
-
-
-
- /*
- * Close the receive dataset, return OK or ERROR
- */
- closeit()
- {
- unsigned int timep[2];
-
- if (stfclose(fout) != 0) {
- fprintf(stderr, "\r\nfile close ERROR\n");
- return ERROR;
- }
- fout = (-1);
-
- if (Modtime) {
- unix2st(Modtime, &timep[0], &timep[1]);
- touch(Pathname, timep);
- }
-
- /* if it is read only by owner on remote, then it is set
- * to read only on the ST, all other file modes are
- * irrelevant.
- */
- if (Filemode)
- {
- unsigned int fmode;
-
- fmode = (unsigned int)(Filemode & 000777);
- if( ((fmode & 0200) == 0) && ((fmode & 0400) != 0) )
- {
- /* it is readonly by owner on the remote, so
- * make it read only on the ST too
- */
- Fattrib(Pathname, 1, 0x01);
- }
- }
- fprintf(stderr,"\n\n%s Closed\n\n", Pathname);
- lsct = 1;
- return OK;
- }
-
- /*
- * Ack a ZFIN packet, let byegones be byegones
- */
- ackbibi()
- {
- register int n;
-
- vfile("ackbibi:");
- Readnum = 1;
- stohdr(0L);
- for (n=4; --n>=0; )
- {
- zshhdr(ZFIN, Txhdr);
- for (;;) {
- switch (readline(100))
- {
- case 'O':
- readline(1); /* Discard 2nd 'O' */
- /* ***** FALL THRU TO ***** */
- case TIMEOUT:
- vfile("ackbibi complete");
- return;
- default:
- break;
- }
- }
- }
- }
-
-
- /*
- * Strip leading ! if present, do shell escape.
- */
- sys2(s)
- register char *s;
- {
- if (*s == '!')
- ++s;
- return stsystem(s);
- }
- /*
- * Strip leading ! if present, do exec.
- */
- exec2(s)
- char *s;
- {
- /** Are you kidding
- if (*s == '!')
- ++s;
- mode(0);
- execl("/bin/sh", "sh", "-c", s);
- **/
- }
-
- /*
- * Touch a file
- */
- #undef Fdatime /* There exist brain damaged versions of osbind.h */
- #define Fdatime(a,b,c) gemdos(0x57,a,b,c)
-
-
- touch(name, timep)
- char *name;
- unsigned int *timep;
- {
- register int handle;
-
- if((handle = Fopen(name, 0)) < 0)
- {
- fprintf(stderr,"*WARNING* Could not set file modification time for %s\n",
- name);
- return;
- }
-
-
- Fdatime(timep, handle, 1);
- Fclose(handle);
- }
-